import { AFFIX_TEMPLATE, AFFIX_REGEXP } from "../../A-FRAME/frame.config";
import { http_send } from "../../A-FRAME/network/HttpService";
import { HSAPIURI, HSAPIStructMap, HSReq, HSRes, HSBody, DEFAULT_BODY } from "./api.config.service";

const ServerURL = "http://am.33t8y678tyy6rt.top/";

export default class ServiceAPI {
	private static used_token: string[] = [];
	private static async send<uri extends HSAPIURI>(api: uri, data?: HSAPIStructMap[uri]['request']['data']) {
		let url = ServerURL + api;

		let request: HSReq<uri> = {} as any;
		request.ccToken = mtec.string.randomToken(5, 36, t => !ServiceAPI.used_token.includes(t));
		request.data = data;
		Object.assign(request, DEFAULT_BODY);
		ServiceAPI.used_token.push(request.ccToken);

		formatRequest(request);
		let response: HSRes<uri> = await http_send(url, request, 'POST');
		parseResponse(response);

		return response;
	}
	/**
	 * 初始化用户
	 * @param deviceId 
	 * @param country 
	 * @returns 
	 */
	public static async initUser(
		deviceId: HSBody<HSAPIURI.UserInit>['deviceId'],
		country: HSBody<HSAPIURI.UserInit>['country']
	) {
		let response = await ServiceAPI.send(HSAPIURI.UserInit, { deviceId, country });
		return response.success ? response.result : void 0;
	}
	/**
	 * 获取用户信息
	 * @param userId 
	 * @returns 
	 */
	public static async userInfo(
		userId: HSBody<HSAPIURI.UserInfo>['userId']
	) {
		let response = await ServiceAPI.send(HSAPIURI.UserInfo, { userId });
		return response.success ? response.result : void 0;
	}
	/**
	 * 地域配置数据
	 * @param country 
	 * @returns 
	 */
	public static async ConfCountry(
		country: HSBody<HSAPIURI.ConfCountry>['country']
	) {
		let response = await ServiceAPI.send(HSAPIURI.ConfCountry, { country });
		return response.success ? response.result : void 0;
	}
	/**
	 * 项目其他配置
	 * @param userId 
	 * @returns 
	 */
	public static async ConfCommon(
		userId: HSBody<HSAPIURI.ConfCommon>['userId']
	) {
		let response = await ServiceAPI.send(HSAPIURI.ConfCommon, { userId });
		return response.success ? response.result : void 0;
	}
	/**
	 * 提现配置数据
	 * @param userId 
	 * @returns 
	 */
	public static async WithdrawConfig(
		userId: HSBody<HSAPIURI.WithdrawConfig>['userId']
	) {
		let response = await ServiceAPI.send(HSAPIURI.WithdrawConfig, { userId });
		return response.success ? response.result : void 0;
	}
	/**
	 * 新人现金奖励数值获取
	 * @param userId 
	 * @param getCashType 
	 * @returns 
	 */
	public static async GetNewComerReward(
		userId: HSBody<HSAPIURI.GetNewComerReward>['userId']
	) {
		let response = await ServiceAPI.send(HSAPIURI.GetNewComerReward, { userId });
		return response.success ? response.result : void 0;
	}
	/**
	 * 抽奖结果获取
	 * @param userId 
	 * @returns 
	 */
	public static async LotteryConfig(
		userId: HSBody<HSAPIURI.LotteryConfig>['userId']
	) {
		let response = await ServiceAPI.send(HSAPIURI.LotteryConfig, { userId });
		return response.success ? response.result : void 0;
	}
	/**
	 * 强弹面板现金数值获取
	 * @param userId 
	 * @returns 
	 */
	public static async ForcePopConfig(
		userId: HSBody<HSAPIURI.ForcePopConfig>['userId']
	) {
		let response = await ServiceAPI.send(HSAPIURI.ForcePopConfig, { userId });
		return response.success ? response.result : void 0;
	}
	/**
	 * 强弹面板现金领取上报
	 * @param userId 
	 * @param packCash 
	 * @param packGetType 
	 * @returns 
	 */
	public static async ForcePopReport(
		userId: HSBody<HSAPIURI.ForcePopReport>['userId'],
		packCash: HSBody<HSAPIURI.ForcePopReport>['packCash'],
		packGetType: HSBody<HSAPIURI.ForcePopReport>['packGetType']
	) {
		let response = await ServiceAPI.send(HSAPIURI.ForcePopReport, { userId, packCash, packGetType });
		return response.success ? response.result : void 0;
	}
	/**
	 * 完成任务现金领取上报
	 * @param userId 
	 * @param cash 
	 * @returns 
	 */
	public static async MissionReport(
		userId: HSBody<HSAPIURI.MissionReport>['userId'],
		taskId: HSBody<HSAPIURI.MissionReport>['taskId'],
		isTaskGetDouble: HSBody<HSAPIURI.MissionReport>['isTaskGetDouble']
	) {
		let response = await ServiceAPI.send(HSAPIURI.MissionReport, { userId, taskId, isTaskGetDouble });
		return response.success ? response.result : void 0;
	}
	/**
	 * 消除成功上报
	 * @param userId 
	 * @param isFreshGuide
	 * @returns 
	 */
	public static async EliminateReport(
		userId: HSBody<HSAPIURI.EliminateReport>['userId'],
		isFreshGuide: HSBody<HSAPIURI.EliminateReport>['isFreshGuide']
	) {
		let response = await ServiceAPI.send(HSAPIURI.EliminateReport, { userId, isFreshGuide });
		return response.success ? response.result : void 0;
	}
	
	/**
	 * 发起提现请求
	 * @param userId 
	 * @param withdrawLevel 
	 * @param account 
	 * @param withdrawCash 
	 * @param accountType 
	 * @param concatName 
	 * @param withdrawChannel 
	 * @returns 
	 */
	public static async WithDraw(
		userId: HSBody<HSAPIURI.WithDraw>['userId'],
		withdrawLevel: HSBody<HSAPIURI.WithDraw>['withdrawLevel'],
		account: HSBody<HSAPIURI.WithDraw>['account'],
		withdrawCash: HSBody<HSAPIURI.WithDraw>['withdrawCash'],
		accountType: HSBody<HSAPIURI.WithDraw>['accountType'],
		concatName: HSBody<HSAPIURI.WithDraw>['concatName'],
		withdrawChannel: HSBody<HSAPIURI.WithDraw>['withdrawChannel'],
	) {
		let response = await ServiceAPI.send(HSAPIURI.WithDraw, { userId, withdrawLevel, account, withdrawCash, accountType, concatName, withdrawChannel });
		return response.success ? response.result : void 0;
	}
}

function formatRequest(request: any) {
	let list = [];

	if (typeof request == 'object' && !Array.isArray(request)) {
		list.unshift(request);
	}

	while (list.length > 0) {
		let item = list.pop();
		if (Array.isArray(item)) {
			item.forEach(el => {
				if (typeof el == 'object') {
					list.unshift(el);
				}
			});
		} else {
			for (let [key, value] of Object.entries(item)) {
				if (typeof value == 'object') {
					list.unshift(value);
				}

				Reflect.deleteProperty(item, key);
				Reflect.set(item, AFFIX_TEMPLATE.replace('key', key), value);
			}
		}
	}

	return request;
}

function parseResponse(response: any) {
	let list = [];

	if (typeof response == 'object' && !Array.isArray(response)) {
		list.unshift(response);
	}

	while (list.length > 0) {
		let item = list.pop();
		if (Array.isArray(item)) {
			item.forEach(el => {
				if (typeof el == 'object') {
					list.unshift(el);
				}
			});
		} else if (item) {
			for (let [key, value] of Object.entries(item)) {
				if (typeof value == 'object') {
					list.unshift(value);
				}

				Reflect.deleteProperty(item, key);
				Reflect.set(item, key.replace(AFFIX_REGEXP, '$1'), value);
			}
		}
	}

	return response;
}